
#ifndef __DEBUG_H
#define __DEBUG_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

//#define errprint(k) magical_errprint(k, __PRETTY_FUNCTION__)
//#define errprintpd(k, p, l) magical_errprint(k, p)

#ifdef VALGRIND_HACKS
#include <valgrind/valgrind.h>
#endif

#ifdef __WIN32__
#define strtok_r strtok_s
#define va_copy(d, s) ((d) = (s))
#endif

#ifndef __WIN32__
#define errprint(k, ...) magical_errprint_moredetail(__PRETTY_FUNCTION__, __LINE__, k, ## __VA_ARGS__)
#define errprintpd(k, p, l, ...) magical_errprint_moredetail(p, l, k, ## __VA_ARGS__)
#else
#define errprint(k, ...) magical_errprint_moredetail(__FILE__, __LINE__, k, ## __VA_ARGS__)
#define errprintpd(k, p, l, ...) magical_errprint_moredetail(p, l, k, ## __VA_ARGS__)
#endif

static void magical_errprint(const char *pretty, const char *k, ...)
{
   va_list fmtargs;
   va_start(fmtargs, k);
   char *__errmsg_buffer = (char *)malloc(sizeof(char)*(strlen(pretty)+strlen(k)+1));
   if (__errmsg_buffer == NULL) fprintf(stderr, "%s - malloc unavailable\n", pretty);
   memcpy(__errmsg_buffer, pretty, strlen(pretty)+1);
   int __charno = 0;
   while (__errmsg_buffer[__charno++] != ' ');
   int __charno_2 = __charno;
   while (__errmsg_buffer[++__charno_2] != '(');
   __errmsg_buffer[__charno_2] = '\0';
   fprintf(stderr, "%s: ", &(__errmsg_buffer[__charno]));
   vfprintf(stderr, k, fmtargs);
   va_end(fmtargs);
   fprintf(stderr, "\n");
   free(__errmsg_buffer);
}

static void magical_errprint_moredetail(const char *pretty, int line, const char *k, ...)
{
   va_list fmtargs;
   va_start(fmtargs, k);
   char *__errmsg_buffer = (char *)malloc(sizeof(char)*(strlen(pretty)+32+strlen(k)+1));
   if (__errmsg_buffer == NULL) fprintf(stderr, "%s:%d - malloc unavailable\n", pretty, line);
   memcpy(__errmsg_buffer, pretty, strlen(pretty)+1);
   int lastbrack = 0, count = 0;
   while (__errmsg_buffer[count] != '\0')
   {
      if (__errmsg_buffer[count] == '(') lastbrack = count;
      count++;
   }
   __errmsg_buffer[lastbrack] = '\0';
   char *remaining = NULL;
   char *token = strtok_r(__errmsg_buffer, " ", &remaining);
   char *lasttoken = NULL;
   while (token != NULL)
   {
      lasttoken = token;
      token = strtok_r(NULL, " ", &remaining);
   }
   if (lasttoken)
   {
      int tlen = strlen(lasttoken);
      memmove(__errmsg_buffer, lasttoken, sizeof(char)*tlen);
      __errmsg_buffer[tlen] = '\0';
   } else memcpy(__errmsg_buffer, pretty, strlen(pretty)+1);
   fprintf(stderr, "%s:%d: ", __errmsg_buffer, line);
   vfprintf(stderr, k, fmtargs);
   va_end(fmtargs);
   fprintf(stderr, "\n");
#ifdef VALGRIND_HACKS
   VALGRIND_PRINTF_BACKTRACE("");
#endif
   free(__errmsg_buffer);
}

#endif
